﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace UDPTester
{
   public class ConvertHelper
    {
        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="data"></param>
        /// <param name="bFormat">如果为True就加入空格</param>
        /// <returns></returns>
        public static string ByteArrayToHexString(byte[] data, bool bFormat = true)
        {
            StringBuilder sb = new StringBuilder(data.Length * 3);
            foreach (byte b in data)
            {
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').PadRight(3, ' '));
            }
            string strResult = sb.ToString().Trim().ToUpper();
            if (!bFormat)
            {
                strResult = strResult.Replace(" ", "");
            }

            return strResult;
        }

        /// <summary>
        /// 16进制字符串转字节数组
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
            {
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            }
            return buffer;
        }

        /// <summary>
        /// 给定数据，填充CRC,CRC高位在前、低位在后
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] CalCRC16a(byte[] data)
        {
            byte CRC16Lo = 0;
            byte CRC16Hi = 0;

            byte CL = 0;
            byte CH = 0;

            byte SaveHi = 0;
            byte SaveLo = 0;      

            short Flag = 0;         

            CRC16Lo = (byte)0xFF;
            CRC16Hi = (byte)0xFF;

            CL = (byte)0x1;
            CH = (byte)0xA0;

            for (int i = 0; i <= data.Length - 3; i++)
            {
                CRC16Lo = Convert.ToByte(CRC16Lo ^ data[i]);
                // 每一个数据与CRC寄存器进行异或 
                for (Flag = (short)0; Flag <= 7.0; Flag = Convert.ToInt16(Flag + 1))
                {
                    SaveHi = CRC16Hi;
                    SaveLo = CRC16Lo;

                    CRC16Hi = Convert.ToByte(CRC16Hi / 2);
                    // 高位右移一位 
                    CRC16Lo = Convert.ToByte(CRC16Lo / 2);
                    // 低位右移一位 

                    if ((SaveHi & 0x1) == 0x1)
                    {
                        // 如果高位字节最后一位为1 
                        CRC16Lo = Convert.ToByte(CRC16Lo | 0x80);
                        // 则低位字节右移后前面补1 
                    }
                    // 否则自动补0 
                    if ((SaveLo & 0x1) == 0x1)
                    {
                        // 如果LSB为1，则与多项式码进行异或 
                        CRC16Hi = Convert.ToByte(CRC16Hi ^ CH);
                        CRC16Lo = Convert.ToByte(CRC16Lo ^ CL);
                    }
                }
            }

            data[data.Length - 2] = CRC16Lo;
            data[data.Length - 1] = CRC16Hi;

            return data;
        }
    }
}
